<template>
  <view class="lp-search-select__container">
    <u-navbar
        :is-fixed="true"
        :height="navBarProps.height"
        :back-icon-color="navBarProps.backIconColor"
        :back-icon-name="navBarProps.backIconName"
        :back-icon-size="navBarProps.backIconSize"
        :back-text="navBarProps.backText"
        :back-text-style="navBarProps.backTextStyle"
        :z-index="navBarProps.zIndex"
        :is-back="navBarProps.isBack"
        :background="navBarProps.background"
        :border-bottom="navBarProps.borderBottom"
        :custom-back="navBarProps.customBack"
    >
      <u-search
          class="lp-search-select__navbar-search"
          v-model="queryForm[keyword]"
          :shape="searchProps.shape"
          :bg-color="searchProps.bgColor"
          :border-color="searchProps.borderColor"
          :placeholder="searchProps.placeholder"
          :clearabled="searchProps.clearabled"
          :focus="searchProps.focus"
          :show-action="searchProps.showAction"
          :action-text="searchProps.actionText"
          :action-style="searchProps.actionStyle"
          :input-align="searchProps.inputAlign"
          :height="searchProps.height"
          :search-icon-color="searchProps.searchIconColor"
          :color="searchProps.color"
          :placeholder-color="searchProps.placeholderColor"
          :margin="searchProps.margin"
          :maxlength="searchProps.maxlength"
          :input-style="searchProps.inputStyle"
          :search-icon="searchProps.searchIcon"
          @search="search"
          @custom="search"
          @clear="search"
      ></u-search>
    </u-navbar>
    <view ref="list"
          class="lp-search-select__list-wrap"
          v-if="list.length">
      <view
          class="lp-search-select__list-item"
          v-for="(item, index) in list"
          :key="item[valueName]"
          @click.native="checkboxChange(item)"
      >
        <view>
          <slot name="row" :row="item">
            <text class="lp-search-select__item-text">{{ item[labelName] }}</text>
          </slot>
          <checkbox
              class="lp-multiple-select__item-checkbox"
              v-if="!isOnlySearch"
              :value="item[labelName]"
              :checked="item.checked"
              :disabled="item.disabled"
              :color="checkboxColor"
          />
        </view>
      </view>

      <view class="lp-search-select__bottom-btn-groups" v-show="!isOnlySearch">
        <u-button :ripple="true" size="medium" shape="circle" @click="cancel">{{ cancelText }}</u-button>
        <u-button type="primary" size="medium" :ripple="true" shape="circle" @click="confirm">
          <span v-if="mode === 'multiple'">({{ selectedListLength }})</span>
          {{  confirmText  }}</u-button>
      </view>
      <u-loadmore v-if="loadMoreShow" :load-text="loadTips" :status="status" @loadmore="loadMore" />
    </view>

    <!--  empty  -->
    <u-empty
        v-if="loading === false && list.length === 0"
        class="lp-search-select__empty"
        mode="list"
        color="#8E8E9D"
        text="暂无数据/(ㄒoㄒ)/~~"
    ></u-empty>
  </view>
</template>

<script>
// ------------------外部资源
import qs from "qs";
// ------------------内部公共
// ------------------内部私有
export default {
  name: 'lp-search-select',
  inheritAttrs: false,
  props: {
    request: {
      type: Function,
      default() {
        return uni.request
      },
      required: true
    },
// 接口
    url: {
      type: String,
      default: '',
      required: true
    },
// 是否触发了下拉加载
    isPullDownRefresh: {
      type: Boolean,
      default: false,
      required: true
    },
// 是否触发了触底事件
    isReachBottom: {
      type: Boolean,
      default: false,
      required: true
    },

// 底部加载的文案
    loadText: {
      type: Object,
      default() {
        return {
          loadmore: '轻轻上拉',
          loading: '努力加载中',
          nomore: '我是有底线的~'
        }
      }
    },

// 主键
    valueName: {
      type: String,
      default: 'id'
    },

// 要显示的字段
    labelName: {
      type: String,
      default: 'label'
    },

// 要搜索的字段
    keyword: {
      type: String,
      default: 'keyword'
    },

// 分页数
    pageSize: {
      type: [Number, String],
      default: 20
    },

// 默认查询参数
    query: {
      type: Object,
      default() {
        return {}
      }
    },

// 单选、多选
    mode: {
      type: String,
      default: 'multiple',
      validator: function (value) {
        // 这个值必须匹配下列字符串中的一个
        return ['single', 'multiple'].indexOf(value) !== -1
      }
    },

// 多选时最大选择数
    max: {
      type: Number,
      default: 999
    },

// 只搜索查看，没有底部按钮和checkBox
    isOnlySearch: {
      type: Boolean,
      default: false
    },

    // 取消按钮文字
    cancelText: {
      type: String,
      default: '取消'
    },
    // 确认按钮文字
    confirmText: {
      type: String,
      default: '确认'
    },
    // 默认选中值
    defaultSelected: {
      type: [Array, Number, String],
      default() {
        return []
      }
    },

    // checkbox 颜色
    checkboxColor: {
      type: String,
      default: '#007aff'
    },
    // 是否使用qs模块序列化参数
    qsStringify: {
      type: Boolean,
      default: false
    },
    // 导航栏属性
    navBarAttrs: {
      type: Object,
      default() {
        return {}
      }
    },

// 搜索组件属性
    searchAttrs: {
      type: Object,
      default() {
        return {}
      }
    }
  },
  components: {},
  data() {
    return {
      loading: true, // 页面loading
      loadMoreShow: false, // 是否显示loadmore
      isInit: false, // list初始
      systemInfo: {}, // 系统信息
      list: [],
      queryForm: {
        pageSize: 20, // 请求数量
        curPage: 0, // 当前请求页
      },
      totalRows: 0, // 总条数
      totalPage: 0, // 总共页数
      status: 'loadmore', // 加载更多状态
      selectedIds: [], // 选择的id数据
      selectedListLength: 0, // 选择的id数据
      selectedList: [], // 选择的row数据
      defaultChecked: [], // 默认选中值
    }
  },
  watch: {
// 下拉
    isPullDownRefresh: function (val) {
      if (val) {
        this.queryForm.curPage = 0
        this.isInit = true
        this.$emit('update:isReachBottom', false)
        this.getList()
      }
    },

// 上拉
    isReachBottom: function (val) {
      if (val) {
        if (this.status === 'nomore') return
        this.loadMore()
      }
    }
  },
  computed: {
// 底部加载的文案
    loadTips: function () {
      const loadTips = {
        loadmore: '轻轻上拉',
        loading: '努力加载中',
        nomore: '我是有底线的~'
      }
      return {
        ...loadTips,
        ...this.loadText,
      }
    },

    // 导航栏属性
    navBarProps: function () {
      const navBarAttrs = {
        height: 44,
        backIconColor: '#606266',
        backIconName: 'nav-back',
        backIconSize: 30,
        backText: '',
        backTextStyle: { color: '#606266' },
        zIndex: 980,
        isBack: true,
        background: { backgroundImage: 'linear-gradient(45deg, rgb(28, 187, 180), rgb(141, 198, 63))' },
        borderBottom: true,
        customBack: null
      }
      return {
        ...navBarAttrs,
        ...this.navBarAttrs,
      }
    },

    // 搜索组件属性
    searchProps: function () {
      const searchAttrs = {
        shape: 'round',
        bgColor: '#f2f2f2',
        borderColor: '',
        placeholder: '请输入关键字',
        clearabled: true,
        focus: true,
        showAction: true,
        actionText: '搜索',
        actionStyle: {},
        inputAlign: 'left',
        height: 64,
        searchIconColor: '',
        color: '#606266',
        placeholderColor: '#909399',
        margin: '',
        maxlength: -1,
        inputStyle: {},
        searchIcon: 'search',
      }
      return {
        ...searchAttrs,
        ...this.searchAttrs,
      }
    },

    // 可选最大数量
    maxCount() {
      return this.mode === 'multiple' ? this.max : 1
    }
  },
  created() {
    this.systemInfo = uni.getSystemInfoSync()
    this.$set(this.queryForm, this.keyword, '')
    this.queryForm.pageSize = this.pageSize
    this.defaultChecked = this.defaultSelected
    this.getList()
  },
  mounted() {},
  methods: {
    /**
     * [camelCaseToHyphen 将驼峰命名转换为连字符]
     * @param  {[string]} str [驼峰命名的字符串]
     * @return {[string]}     [连字符的字符串]
     */
    camelCaseToHyphen(str) {
      return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()
    },
// 选中某个复选框时，由checkbox时触发
    checkboxChange(data) {
      if (this.isOnlySearch || data.disabled) return;
      if (data.checked) {
        data.checked = false
        const index = this.selectedList.findIndex(item => item[this.valueName] === data[this.valueName])
        this.selectedList.splice(index, 1)
        this.selectedIds.splice(index, 1)
      } else {
        if (this.selectedIds.length >= this.maxCount) {
          uni.showToast({
            title: `最多可选${this.maxCount}项`,
            icon: 'none'
          });
          return;
        }
        data.checked = true
        this.selectedList.push(data)
        this.selectedIds.push(data[this.valueName])
      }
      this.selectedListLength = this.selectedIds.length
      console.log('selectedIds', this.selectedIds);
    },

// 顶部搜索
    search() {
      this.backToTop()
      this.isInit = true
      this.queryForm.curPage = 0
      this.getList()
      this.$emit('update:isReachBottom', false)
    },

// 回到顶部
    backToTop() {
      uni.pageScrollTo({
        scrollTop: 0,
        duration: 0
      });
    },

// 获取列表
    getList() {
      uni.showLoading({
        title: '正在加载...'
      })
      this.loading = true
      const params = {
        ...this.queryForm,
        ...this.query
      }
      const queryParams = this.qsStringify ? qs.stringify(params) : params
      this.request(this.url, 'POST', queryParams)
          .then(({ flag, data: { dataList = [], totalRows }}) => {
            uni.hideLoading()
            this.loading = false
            if (flag === 1) {
              this.totalRows = totalRows
              this.totalPage = Math.ceil(totalRows / this.queryForm.pageSize)
              if (this.queryForm.curPage + 1 >= this.totalPage) {
                this.status = 'nomore'
              }  else {
                this.status = 'loadmore'
              }

              // ======做回显======
              const list = [...dataList]
              let defaultSelected = []
              if (this.mode === 'single') {
                defaultSelected = this.defaultChecked.toString()
              } else {
                defaultSelected = this.defaultChecked.map(item => item.toString())
              }
              for(const item of list) {
                if (this.mode === 'single') {
                  if (defaultSelected === item[this.valueName].toString()) {
                    item.checked = true
                  }
                } else {
                  if (defaultSelected.includes(item[this.valueName].toString())) {
                    item.checked = true
                    this.selectedList.push(item)
                  }
                }
              }
              // ======回显======

              if (this.isInit) {
                this.list = dataList
              } else {
                this.list = [...this.list, ...dataList]
              }
              this.$emit('update:isPullDownRefresh', false)
              uni.stopPullDownRefresh()
              this.isInit = false

              this.$nextTick(() => {
                this.getLoadMoreShow()
              })
            }
          }).catch(err => {
        uni.hideLoading()
        this.loading = false
        this.list.length = 0
        console.error(err)
        uni.stopPullDownRefresh()
        this.isInit = false
      })
    },

// 获取是否显示loadmore
    getLoadMoreShow() {
// console.log('screenHeight', this.systemInfo.screenHeight)
// console.log('offsetHeight', this.$refs.list?.$el?.offsetHeight)
// 未超出屏幕宽度，loadMore不展示
      this.loadMoreShow = !!(this.list.length && ((((this.systemInfo.screenHeight + this.systemInfo.statusBarHeight - 105) || (700 - 105)) / (this.$refs.list?.$el?.offsetHeight || 700)) < 1))
    },

// 加载更多
    loadMore() {
      if (this.queryForm.curPage >= this.totalPage) return
      this.status = 'loading'
      this.queryForm.curPage = ++this.queryForm.curPage
      if (this.queryForm.curPage >= this.totalPage) this.status = 'nomore'
      else this.status = 'loading'
      this.getList()
      this.$emit('update:isReachBottom', false)
    },

    cancel() {
      this.$emit('cancel')
    },

    // 确认
    confirm() {
      if (this.mode === 'single') {
        const selected = this.selectedList && this.selectedList.length ? this.selectedList[0] : {}
        console.log('selected', selected);
        this.$emit('confirm', selected)
      } else {
        console.log('this.selectedList', this.selectedList);
        console.log('this.selectedIds', this.selectedIds);
        this.$emit('confirm', this.selectedList, this.selectedIds)
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.lp-search-select__container {
  .lp-search-select__navbar-search {
    width: 100%;
  }

  .lp-search-select__list-wrap {
    width: 100%;
    background-color: $uni-bg-color;

    .lp-search-select__list-item {
      display: block;
      position: relative;
    }

    .lp-search-select__item-text {
      display: inline-block;
      width: 100%;
      padding: $uni-spacing-col-base;
      background-color: $uni-bg-color;
      border-bottom: 2rpx dashed $uni-border-color;
    }

    .lp-multiple-select__item-checkbox {
      position: absolute;
      right: 16rpx;
      top: 50%;
      transform: translateY(-50%) scale(0.7);
      color: $uni-color-primary;
    }

    .lp-search-select__bottom-btn-groups {
      display: flex;
      justify-content: space-around;
      position: fixed;
      bottom: 30px;
      left: 0;
      z-index: 2;
      width: 100%;
      .u-btn {
        display: inline-block;
        width: 45%;
      }
    }
  }
}
.u-load-more-wrap {
  padding-bottom: 10rpx;
}

.lp-search-select__empty {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
</style>
